package com.hd.service.job.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.expression.ParseException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.hd.dao.BaseDao;
import com.hd.entity.job.QuartzScheduleJob;
import com.hd.job.QuartzJobFactory;
import com.hd.service.job.QuartzScheduleJobService;
import com.hd.util.JsonUtil;
import com.hd.util.QuartzCronDateUtils;
import com.hd.util.StringUtils;
import com.hd.util.result.PageInfo;
@Service("quartzScheduleJobService")
public class QuartzScheduleJobServiceImpl implements QuartzScheduleJobService {

	@Autowired
    private Scheduler scheduler;
	@Autowired
	private BaseDao<QuartzScheduleJob,String>scheduleJobDao;

	/**
	 * 添加简单任务,只运行一次的任务
	 */
    @Override
    public void addSimpleJob(String jobName, String jobGroup, String className, String methodName, String params, String runDateTime,String desc) throws SchedulerException, ParseException {
        //判断是否已存在相同jobName,jobGroup,若存在则删除
        if (scheduler.getJobDetail(JobKey.jobKey(jobName, jobGroup)) != null) {
            deleteJob(jobName, jobGroup);
        }
        JobDetail jobDetail = JobBuilder.newJob(QuartzJobFactory.class).withIdentity(jobName, jobGroup).build();
        ArrayList paramArray=QuartzCronDateUtils.getScheduleParamArray(params);
        System.out.println(paramArray);
        //任务具体执行的内容封装,返回给job统一入口
        QuartzScheduleJob job = new QuartzScheduleJob(jobName, jobGroup, jobName, jobGroup, className, methodName, paramArray, null, runDateTime, null);
        job.setStatus(1);
        job.setParams(params);
        job.setDesc(desc);
        //将我自定义的POJO类存放到DataMap中
		jobDetail.getJobDataMap().put("scheduleJob", job);
        //创建SimpleTrigger,在特定时间仅运行一次
		SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        Date runDate=null;
		try {
			runDate = df.parse(runDateTime);
		} catch (java.text.ParseException e) {
			e.printStackTrace();
		}
        SimpleTrigger trigger = (SimpleTrigger) TriggerBuilder.newTrigger().withIdentity(jobName, jobGroup).
                startAt(runDate).build();
        scheduler.scheduleJob(jobDetail, trigger);
        scheduleJobDao.save(job);
    }


	@Override
	public void addCronJob(String jobName, String jobGroup, String className, String methodName, String params,
			String cron,String desc) throws SchedulerException {
		  //判断是否已存在相同jobName,jobGroup,若存在则删除
        if (scheduler.getJobDetail(JobKey.jobKey(jobName, jobGroup)) != null) {
            deleteJob(jobName, jobGroup);
        }
        //任务具体执行的内容封装,返回给job统一入口
        ArrayList paramArray=QuartzCronDateUtils.getScheduleParamArray(params);
        System.out.println(JsonUtil.toJson(paramArray));
        QuartzScheduleJob job = new QuartzScheduleJob(jobName, jobGroup, jobName, jobGroup, className, methodName, paramArray, cron, null, null);
        //将我自定义的POJO类存放到DataMap中
		 JobDetail jobDetail = JobBuilder.newJob(QuartzJobFactory.class).withIdentity(jobName, jobGroup).build();
		 jobDetail.getJobDataMap().put("scheduleJob", job);
		 TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
         // 触发器名,触发器组  
         triggerBuilder.withIdentity(jobName,jobGroup);
         triggerBuilder.startNow();
         // 触发器时间设定  
         triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
         // 创建Trigger对象
         CronTrigger trigger = (CronTrigger) triggerBuilder.build();
         // 调度容器设置JobDetail和Trigger
         scheduler.scheduleJob(jobDetail, trigger);  
         job.setStatus(1);
         job.setParams(params);
         job.setDesc(desc);
         scheduleJobDao.save(job);
	}

	@Override
	public void updateSimpleJob(String jobName, String jobGroup, String runDateTime)
			throws SchedulerException, ParseException {
		// TODO Auto-generated method stub
		 TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
		  SimpleTrigger trigger = (SimpleTrigger) scheduler.getTrigger(triggerKey);  
	         if (trigger == null) {  
	             return;  
	         }  
	   //创建SimpleTrigger,在特定时间仅运行一次
		SimpleDateFormat df=new SimpleDateFormat("yyyyMMddhhmmss");
		String oldTime = df.format(trigger.getStartTime());
		if(!oldTime.equals(runDateTime)) {
			Date runDate=null;
			try {
				runDate = df.parse(runDateTime);
			} catch (java.text.ParseException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			SimpleTrigger newTrigger = (SimpleTrigger) TriggerBuilder.newTrigger().withIdentity(jobName, jobGroup).
	                startAt(runDate).build();
	        scheduler.rescheduleJob(triggerKey, newTrigger);
	        QuartzScheduleJob scheduleJob = scheduleJobDao.get(QuartzScheduleJob.class, jobName);
	        scheduleJob.setRunDate(runDateTime);
	        scheduleJobDao.update(scheduleJob);
		}
        
	}
	/**
	 * 更新cron表达式
	 */
	@Override
	public void updateCronJob(String jobName, String jobGroup, String cron) throws SchedulerException {
		// TODO Auto-generated method stub
		 TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
         CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);  
         if (trigger == null) {  
             return;  
         }  
         String oldTime = trigger.getCronExpression();  
         if (!oldTime.equalsIgnoreCase(cron)) { 
             // 触发器  
             TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
             // 触发器名,触发器组  
             triggerBuilder.withIdentity(jobName, jobGroup);
             triggerBuilder.startNow();
             // 触发器时间设定  
             triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
             // 创建Trigger对象
             trigger = (CronTrigger) triggerBuilder.build();
             // 方式一 ：修改一个任务的触发时间
             scheduler.rescheduleJob(triggerKey, trigger);
             QuartzScheduleJob scheduleJob = scheduleJobDao.get(QuartzScheduleJob.class, jobName);
             scheduleJob.setCron(cron);
             scheduleJobDao.update(scheduleJob);
         }  

	}
	/**
	 * 移除任务
	 */
	@Transactional
	@Override
	public void deleteJob(String jobName, String jobGroup) throws SchedulerException {
		// TODO Auto-generated method stub
		 TriggerKey triggerKey = TriggerKey.triggerKey(jobName,jobGroup);
         // 停止触发器  
         scheduler.pauseTrigger(triggerKey);
         // 移除触发器  
         scheduler.unscheduleJob(triggerKey);
		 scheduler.deleteJob(JobKey.jobKey(jobName, jobGroup));
		 scheduleJobDao.delete(QuartzScheduleJob.class, jobName);
	}
	/**
	 * 移除所有任务
	 */
	@Transactional
	@Override
	public void deleteAll() throws SchedulerException {
		// TODO Auto-generated method stub
		String hql="from QuartzScheduleJob";
		List<QuartzScheduleJob> scheduleJobs=scheduleJobDao.find(hql);
		if(scheduleJobs.size()>0) {
			for(QuartzScheduleJob scheduleJob:scheduleJobs) {
				 TriggerKey triggerKey = TriggerKey.triggerKey(scheduleJob.getJobName(),scheduleJob.getJobGroup());
		         // 停止触发器  
		         scheduler.pauseTrigger(triggerKey);
		         // 移除触发器  
		         scheduler.unscheduleJob(triggerKey);
				 scheduler.deleteJob(JobKey.jobKey(scheduleJob.getJobName(),scheduleJob.getJobGroup()));
				 scheduleJobDao.delete(scheduleJob);
			}
		}
	}
	/**
	 * 暂停任务
	 */
	@Transactional
	@Override
	public void pauseJob(String jobName, String jobGroup) throws SchedulerException {
		// TODO Auto-generated method stub
		scheduler.pauseJob(JobKey.jobKey(jobName, jobGroup));
		QuartzScheduleJob scheduleJob = scheduleJobDao.get(QuartzScheduleJob.class, jobName);
		scheduleJob.setStatus(2);
		scheduleJobDao.update(scheduleJob);
	}
	/**
	 * 暂停所有任务
	 */
	@Transactional
	@Override
	public void pauseAll() throws SchedulerException {
		// TODO Auto-generated method stub
		scheduler.pauseAll();
		String hql="update QuartzScheduleJob set status=2";
		scheduleJobDao.execute(hql);
	}
	/**
	 * 恢复任务
	 */
	@Transactional
	@Override
	public void resumeJob(String jobName, String jobGroup) throws SchedulerException {
		// TODO Auto-generated method stub
		scheduler.resumeJob(JobKey.jobKey(jobName, jobGroup));
		QuartzScheduleJob scheduleJob = scheduleJobDao.get(QuartzScheduleJob.class, jobName);
		scheduleJob.setStatus(1);
		scheduleJobDao.update(scheduleJob);
	}
	/**
	 * 恢复所有任务
	 */
	@Transactional
	@Override
	public void resumeAll() throws SchedulerException {
		// TODO Auto-generated method stub
		scheduler.resumeAll();
		String hql="update QuartzScheduleJob set status=1";
		scheduleJobDao.execute(hql);
	}
	/**
	 * 关闭所有定时任务
	 */
	@Transactional
	@Override
	public void shutDown() throws SchedulerException {
		// TODO Auto-generated method stub
		if (!scheduler.isShutdown()) {
			scheduler.shutdown();
			String hql="update QuartzScheduleJob set status=0";
			scheduleJobDao.execute(hql);
		}
	}
	/**
	 * 开启所有的定时任务
	 */
	@Transactional
	@Override
	public void startScheduler() throws SchedulerException {
		// TODO Auto-generated method stub
		scheduler.start();
		String hql="update QuartzScheduleJob set status=1";
		scheduleJobDao.execute(hql);
	}


	@Override
	public void selectDataGrid(PageInfo info) {
		Map<String,Object>condition=info.getCondition();
		List<Object>params=new ArrayList<Object>();
		String hql="from QuartzScheduleJob where 1=1";
		if(StringUtils.isNotNull(condition.get("jobName"))) {
			hql+=" and jobName=?";
			params.add(condition.get("jobName"));
		}
		List<QuartzScheduleJob> list = scheduleJobDao.findPage(hql, info.getNowpage(), info.getPagesize(), params);
		int total=scheduleJobDao.findByList(hql,params).size();
		info.setTotal(total);
		info.setRows(list);
		
		
	}


	@Override
	public QuartzScheduleJob get(String jobName) {
		// TODO Auto-generated method stub
		return scheduleJobDao.get(QuartzScheduleJob.class, jobName);
	}
	
	

}
